import json
import time
import uuid
from dataclasses import dataclass
from injector import  inject

from pkg.sqlalchemy import SQLAlchemy
from .base_service import BaseService
import  requests

from ..entitry.account_entitry import EXPIREAT, ACCESS_TOKEN, Account, SEND_SMS_URL, BASE_URL, OAUTH_URL, GET_INFO_RRL, \
    CACHE_PROXY, GET_PROXY_AUAHORIZATION, GET_SECRER_TOKEN, ACCOUNT_PROXY, GET_ORDEER_INFO, PROXY_TOKEN

from ..exception import UnauthorizedException,FailException
from ..lib.sign import get_headers, rsa_encrypt_pkcs1_only
from urllib.parse import urlencode
from redis import Redis
from internal.model import TourGuide,Proxy


@inject
@dataclass
class AccountService(BaseService):
    redis_client: Redis
    db:SQLAlchemy
    #发送验证码
    def send_sms(self,phone:str):
        session_data = requests.session()
        data = {
            "mobile": phone,
            "type": "login",
        }
        headers =  get_headers(SEND_SMS_URL)
        req = session_data.request(
            method="POST",
            url=SEND_SMS_URL,
            json=data,  # 使用json参数自动设置Content-Type和序列化
            headers=headers,
            verify=False,  # 跳过SSL验证
            timeout=30
        )
        req.raise_for_status()
        data_json = req.json()
        return data_json



    #登录
    def login(self,phone:str,id:str,code:str):
        auth_basic = "Basic YXBwOmhvbGx5c21hcnQhQCM="
        session_data = requests.session()
        common_headers = {
            "Accept": "*/*",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
            "Authorization": auth_basic,
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "Origin": BASE_URL,
            "Pragma": "no-cache",
            "Referer": f"{BASE_URL}/login.html",
            "Sec-Fetch-Dest": "empty",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Site": "same-origin",
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0",
            "X-Requested-With": "XMLHttpRequest",
            "sec-ch-ua": '"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": '"macOS"'
        }
        data = {
            "mobile": phone,
            "smsCode": code,
            "deviceId":str(uuid.uuid4()),
            "validCode":"0,0"
        }
        url = f"{OAUTH_URL}?{urlencode(data)}"
        headers = get_headers(url)
        merge_headers = {
            **common_headers,
            **headers,
        }
        req = session_data.request(
            method="POST",
            url=url,
            headers=merge_headers,
            verify=False,  # 跳过SSL验证
            timeout=30
        )
        data_json = req.json()
        if data_json.get("code")==200:
            access_token = data_json.get("data").get("access_token")
            user = self.get_info(access_token)
            cache = ACCESS_TOKEN.format(user_id=user.get("data").get("userId"))
            self.redis_client.setex(cache, EXPIREAT, access_token)
            with self.db.auto_commit():
                guide = self.db.session.query(TourGuide).filter(TourGuide.id == id).one_or_none()
                self.update(
                    guide,
                    user_id=user.get("data").get("userId"),
                )
        return data_json

    #获取订单信息
    def getorder_info(self,secret_id:str,secret_key:str):
        token_key = PROXY_TOKEN.format(secret_id=secret_id)
        token=""
        if self.redis_client.exists(token_key):
            token = self.redis_client.get(token_key)
        else:
            secret_token = requests.post(
                url=GET_SECRER_TOKEN,
                data={
                    "secret_id": secret_id,
                    "secret_key": secret_key
                }
            )
            if secret_token.status_code == 400:
                raise FailException("secret信息错误")
            elif secret_token.status_code == 407:
                raise FailException("订单已到期或不存在")

            secret_token_json = secret_token.json()

            #成功
            if secret_token_json.get("code") == 0:
                    token = secret_token_json.get('data').get('secret_token')

        order_req = requests.get(f"{GET_ORDEER_INFO}?secret_id={secret_id}&signature={token}")
        order_info_json = order_req.json()
        if order_info_json.get("code") == 0:
            return order_info_json.get("data").get("status")


    #获取代理信息
    def add_proxy(self,secret_id:str,secret_key:str):
        key = CACHE_PROXY.format(secret_id=secret_id)
        token_key = PROXY_TOKEN.format(secret_id=secret_id)
        #prroxy = self.db.session.query(Proxy).filter(Proxy.user_name==user_name,Proxy.password==password).one_or_none()
        print(GET_SECRER_TOKEN)
        secret_token = requests.post(
        url=GET_SECRER_TOKEN,
        data={
                "secret_id": secret_id,
                "secret_key": secret_key
        }
        )
        if secret_token.status_code == 400:
            raise FailException("secret信息错误")
        elif secret_token.status_code == 407:
            raise FailException("订单已到期或不存在")
        secret_token_json = secret_token.json()
        print(secret_token_json)
        if secret_token_json.get("code")==0:
                if not self.redis_client.exists(key):
                    auth = requests.get(f"{GET_PROXY_AUAHORIZATION}?secret_id={secret_id}&signature={secret_token_json.get('data').get('secret_token')}&plaintext=1")
                    auth_json = auth.json()
                    print(auth_json)
                    if auth_json.get("code") == 0:
                       self.redis_client.setex(key,3600,json.dumps(auth_json.get("data"),ensure_ascii=False))
                       self.redis_client.setex(token_key,secret_token_json.get('data').get("expire"),secret_token_json.get('data').get('secret_token'))
                    else:
                        raise  FailException(auth_json.get("msg"))
        else:
            raise  FailException(secret_token_json.get("msg"))



    #获取用户信息
    def get_info(self,token:str):
        session_data = requests.session()
        headers = get_headers(GET_INFO_RRL,token)
        merge_headers = {
            **headers,
            "Authorization": f"Bearer {token}"
        }
        req = session_data.request(
            method="get",
            url=GET_INFO_RRL,
            headers=merge_headers,
            verify=False,  # 跳过SSL验证
            timeout=30
        )
        data = req.json()
        code =  data.get("code")
        if code ==401 or req.status_code ==401:
            raise UnauthorizedException("token过期，请更换后尝试")
        return data
